import { Map, TileLayer, VectorLayer } from 'maptalks'
import { pickCenterPoint, calcResolutionForDistance, calcDistanceForResolution, toDegrees, toRadians } from "./core";

const cesiumDiv = document.getElementById('container3d')
const mtkDiv = document.getElementById('map')

const options = {
    animation: false,
    baseLayerPicker: false,
    vrButton: false,
    fullscreenButton: false,
    geocoder: false,
    homeButton: false,
    infoBox: true,
    sceneModePicker: false,
    selectionIndicator: false,
    timeline: false,
    navigationHelpButton: false,
    navigationInstructionsInitiallyVisible: true,
    scene3DOnly: false,
    shouldAnimate: false,
    creditContainer: document.createElement("div"),
    // terrainExaggeration: 1,
    // terrainProvider: new Cesium.EllipsoidTerrainProvider(),
    // imageryProvider: ,
    contextOptions: {
        webgl: {
            alpha: true,
            depth: false,
            stencil: true,
            antialias: true,
            premultipliedAlpha: true,
            preserveDrawingBuffer: true,//通过canvas.toDataURL()实现截图需要将该项设置为true
            failIfMajorPerformanceCaveat: true
        }, allowTextureFilterAnisotropic: true
    },
    baseLayer: new Cesium.ImageryLayer(new Cesium.UrlTemplateImageryProvider({
        name: 'arcgisonline',
        url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
    })),
    baseLayerPicker: false,
}


const cViewer = new Cesium.Viewer('container3d', options)

let mMap = new Map('map', {
    zoom: 5,
    center: [114, 30],
    baseLayer: new TileLayer('base', {
        urlTemplate: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
    })
})

/**
 * @param input Input coordinate array.
 * @param opt_output Output array of coordinate values.
 * @param opt_dimension Dimension.
 * @return Input coordinate array (same array as input).
 */
function identityProjection(input, opt_output, opt_dimension) {
    const dim = opt_dimension || input.length;
    if (opt_output) {
        for (let i = 0; i < dim; ++i) {
            opt_output[i] = input[i];
        }
    }
    return input;
}

const camera = cViewer.camera
const scene = cViewer.scene

const res0 = mMap.getSpatialReference().getResolutions()[0]


let zoomToSwitch = -1

let switch2mMap = function () {
    const ellipsoid = Cesium.Ellipsoid.WGS84;
    // center
    let bestTarget = pickCenterPoint(scene)
    if (!bestTarget) {
        //TODO: how to handle this properly ?
        const globe = scene.globe;
        const carto = camera.positionCartographic.clone();
        const height = globe.getHeight(carto);
        carto.height = height || 0;
        bestTarget = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto);
    }
    const distance = Cesium.Cartesian3.distance(bestTarget, camera.position);
    console.info('distance', distance)
    const bestTargetCartographic = ellipsoid.cartesianToCartographic(bestTarget)
    let center = identityProjection([toDegrees(bestTargetCartographic.longitude), toDegrees(bestTargetCartographic.latitude)])
    mMap.setCenter(center);
    console.info('center', center)

    // resolution
    let resolution = calcResolutionForDistance(distance, bestTargetCartographic ? bestTargetCartographic.latitude : 0, scene)
    console.log(resolution);

    const curZoom = Math.log(res0 / resolution) / Math.log(2)
    console.log(curZoom);

    // heading
    // const up = cCamera.up;
    // const right = cCamera.right;
    // const normal = new Cesium.Cartesian3(-bestTarget.y, bestTarget.x, 0); // what is it?
    // const bearing = Cesium.Cartesian3.angleBetween(right, normal);
    // console.log(bearing)
    mMap.setView({
        zoom: curZoom,
        pitch: toDegrees(camera.pitch + Math.PI / 2),
        bearing: toDegrees(camera.heading)
    })

    return curZoom


}

let switch2cesium = function () {
    const zoom = mMap.getZoom()
    const centerXY = [mMap.getCenter().x, mMap.getCenter().y]
    const mPitch = mMap.getPitch()
    const mBearing = mMap.getBearing()
    const carto = new Cesium.Cartographic(toRadians(centerXY[0]), toRadians(centerXY[1]))
    if (scene.globe) {
        const height = scene.globe.getHeight(carto);
        carto.height = height || 0;
    }

    const destination = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto);

    const orientation = {
        pitch: toRadians(mPitch) - Math.PI / 2,
        heading: toRadians(mBearing),
        roll: undefined
    };
    camera.setView({
        destination,
        orientation
    })

    const resolution = res0 / Math.pow(2, zoom)
    const distance = calcDistanceForResolution(resolution || 0, toRadians(centerXY[1]), scene)
    console.log('distance', distance);
    camera.moveBackward(distance)
}

cViewer.camera.changed.addEventListener(() => {
    let bestTarget = pickCenterPoint(scene)
    const distance = Cesium.Cartesian3.distance(bestTarget, camera.position);
    if (distance < 4921021.5333821215) {
        zoomToSwitch = switch2mMap()

        cesiumDiv.before(mtkDiv)
    }
    // // TODO
    // 3624.213338699059
})

mMap.on('zoomend', e => {
    if (e.from > e.to && e.to < zoomToSwitch) {
        switch2cesium()
        mtkDiv.before(cesiumDiv)
    }
})
window.getCenter = switch2mMap
window.mMap = mMap
window.cCamera = camera
